﻿module DomainService15
open NUnit.Framework
open RestfulObjects.Mvc
open NakedObjects.Surface
open System.Net
open System.Net.Http
open System.Net.Http.Headers
open System.IO
open Newtonsoft.Json.Linq
open System.Web
open System
open RestfulObjects.Snapshot.Utility 
open RestfulObjects.Snapshot.Constants
open System.Web.Http
open System.Collections.Generic
open System.Linq
open RestTestFunctions
// open System.Json


let GetService(api : RestfulObjectsControllerBase) = 
        let sName = ttc "RestfulObjects.Test.Data.RestDataRepository"
        let url = sprintf  "http://localhost/services/%s" sName

        let args = CreateReservedArgs ""

        api.Request <-  jsonGetMsg(url)
        let result = api.GetService(sName, args)
        let jsonResult = readSnapshotToJson result
        let parsedResult = JObject.Parse(jsonResult)
        let mst = ttc "RestfulObjects.Test.Data.MostSimple"

        let expected = [ TProperty(JsonPropertyNames.ServiceId, TObjectVal(sName));
                         TProperty(JsonPropertyNames.Title, TObjectVal("Rest Data Repository"));
                         TProperty(JsonPropertyNames.Links, TArray([ TObjectJson(makeGetLinkProp RelValues.Self (sprintf "services/%s" sName)  RepresentationTypes.Object sName);
                                                                     TObjectJson(makeGetLinkProp RelValues.DescribedBy (sprintf "domain-types/%s" sName)  RepresentationTypes.DomainType "");
                                                                     //TObjectJson(makeIconLink())
                                                                      ]));
                         TProperty(JsonPropertyNames.Members, TObjectJson([TProperty("AzContributedAction", TObjectJson(makeServiceActionMember "AzContributedAction" sName mst));
                                                                           TProperty("AzContributedActionOnBaseClass", TObjectJson(makeServiceActionMember "AzContributedActionOnBaseClass" sName mst));
                                                                           TProperty("AzContributedActionWithRefParm", TObjectJson(makeServiceActionMember "AzContributedActionWithRefParm" sName mst));
                                                                           TProperty("AzContributedActionWithValueParm", TObjectJson(makeServiceActionMember "AzContributedActionWithValueParm" sName mst));
                                                                           TProperty("CreateTransientMostSimple", TObjectJson(makeServiceActionMemberNoParms "CreateTransientMostSimple" sName mst));
                                                                           TProperty("CreateTransientWithValue", TObjectJson(makeServiceActionMemberNoParms "CreateTransientWithValue" sName (ttc "RestfulObjects.Test.Data.WithValue")));
                                                                           TProperty("CreateTransientWithReference", TObjectJson(makeServiceActionMemberNoParms "CreateTransientWithReference" sName (ttc "RestfulObjects.Test.Data.WithReference")));
                                                                           TProperty("CreateTransientWithCollection", TObjectJson(makeServiceActionMemberNoParms "CreateTransientWithCollection" sName (ttc "RestfulObjects.Test.Data.WithCollection")))
                                                            ]));
                         TProperty(JsonPropertyNames.Extensions, TObjectJson([TProperty(JsonPropertyNames.DomainType, TObjectVal(sName));
                                                                              TProperty(JsonPropertyNames.FriendlyName, TObjectVal("Rest Data Repository"));
                                                                              TProperty(JsonPropertyNames.PluralName, TObjectVal("Rest Data Repositories"));
                                                                              TProperty(JsonPropertyNames.Description, TObjectVal(""));
                                                                              TProperty("serviceType", TObjectVal("menu"));
                                                                              TProperty(JsonPropertyNames.IsService, TObjectVal(true))]) )]

        Assert.AreEqual(HttpStatusCode.OK, result.StatusCode)
        Assert.AreEqual(new typeType( RepresentationTypes.Object, sName), result.Content.Headers.ContentType)
        assertNonExpiringCache result 
        Assert.IsNull(result.Headers.ETag ) 
        compareObject expected parsedResult

let GetContributorService(api : RestfulObjectsControllerBase) = 
        let sName = ttc "RestfulObjects.Test.Data.ContributorService"
        let url = sprintf  "http://localhost/services/%s" sName

        let args = CreateReservedArgs ""

        api.Request <-  jsonGetMsg(url)
        let result = api.GetService(sName, args)
        let jsonResult = readSnapshotToJson result
        let parsedResult = JObject.Parse(jsonResult)
        let mst = ttc "RestfulObjects.Test.Data.MostSimple"

        let expected = [ TProperty(JsonPropertyNames.ServiceId, TObjectVal(sName));
                         TProperty(JsonPropertyNames.Title, TObjectVal("Contributor Service"));
                         TProperty(JsonPropertyNames.Links, TArray([ TObjectJson(makeGetLinkProp RelValues.Self (sprintf "services/%s" sName)  RepresentationTypes.Object sName);
                                                                     TObjectJson(makeGetLinkProp RelValues.DescribedBy (sprintf "domain-types/%s" sName)  RepresentationTypes.DomainType "");
                                                                     //TObjectJson(makeIconLink())
                                                                      ]));
                         TProperty(JsonPropertyNames.Members, TObjectJson([TProperty("ANonContributedAction", TObjectJson(makeServiceActionMemberNoParms "ANonContributedAction" sName mst))]));
                         TProperty(JsonPropertyNames.Extensions, TObjectJson([TProperty(JsonPropertyNames.DomainType, TObjectVal(sName));
                                                                              TProperty(JsonPropertyNames.FriendlyName, TObjectVal("Contributor Service"));
                                                                              TProperty(JsonPropertyNames.PluralName, TObjectVal("Contributor Services"));
                                                                              TProperty(JsonPropertyNames.Description, TObjectVal(""));
                                                                              TProperty("serviceType", TObjectVal("contributor"));
                                                                              TProperty(JsonPropertyNames.IsService, TObjectVal(true))]) )]

        Assert.AreEqual(HttpStatusCode.OK, result.StatusCode)
        Assert.AreEqual(new typeType( RepresentationTypes.Object, sName), result.Content.Headers.ContentType)
        assertNonExpiringCache result 
        Assert.IsNull(result.Headers.ETag ) 
        compareObject expected parsedResult


let GetServiceFormalOnly(api : RestfulObjectsControllerBase) = 
        let sName = ttc "RestfulObjects.Test.Data.RestDataRepository"
        let argS = "x-ro-domain-model=formal"
        let url = sprintf  "http://localhost/services/%s?%s" sName argS

        let args = CreateReservedArgs argS

        api.Request <- jsonGetMsg(url)
        let result = api.GetService(sName, args)
        let jsonResult = readSnapshotToJson result
        let parsedResult = JObject.Parse(jsonResult)
        let mst = ttc "RestfulObjects.Test.Data.MostSimple"

        let expected = [ TProperty(JsonPropertyNames.ServiceId, TObjectVal(sName));
                         TProperty(JsonPropertyNames.Title, TObjectVal("Rest Data Repository"));
                         TProperty(JsonPropertyNames.Links, TArray([ TObjectJson(makeLinkPropWithMethodAndTypes "GET" RelValues.Self (sprintf "services/%s" sName)  RepresentationTypes.Object sName "" false);
                                                                     TObjectJson(makeGetLinkProp RelValues.DescribedBy (sprintf "domain-types/%s" sName)  RepresentationTypes.DomainType "");
                                                                     //TObjectJson(makeIconLink())
                                                                      ]));
                         TProperty(JsonPropertyNames.Members, TObjectJson([TProperty("AzContributedAction", TObjectJson(makeActionMemberFormal "services" "AzContributedAction" sName mst));
                                                                           TProperty("AzContributedActionOnBaseClass", TObjectJson(makeActionMemberFormal "services" "AzContributedActionOnBaseClass" sName mst));
                                                                           TProperty("AzContributedActionWithRefParm", TObjectJson(makeActionMemberFormal "services" "AzContributedActionWithRefParm" sName mst));
                                                                           TProperty("AzContributedActionWithValueParm", TObjectJson(makeActionMemberFormal "services" "AzContributedActionWithValueParm" sName mst));
                                                                           TProperty("CreateTransientMostSimple", TObjectJson(makeActionMemberFormal "services" "CreateTransientMostSimple" sName mst));
                                                                           TProperty("CreateTransientWithValue", TObjectJson(makeActionMemberFormal "services" "CreateTransientWithValue" sName (ttc "RestfulObjects.Test.Data.WithValue")));
                                                                           TProperty("CreateTransientWithReference", TObjectJson(makeActionMemberFormal "services" "CreateTransientWithReference" sName (ttc "RestfulObjects.Test.Data.WithReference")));
                                                                           TProperty("CreateTransientWithCollection", TObjectJson(makeActionMemberFormal "services" "CreateTransientWithCollection" sName (ttc "RestfulObjects.Test.Data.WithCollection"))) ]));

                         TProperty(JsonPropertyNames.Extensions, TObjectJson([]) )]

        Assert.AreEqual(HttpStatusCode.OK, result.StatusCode)
        Assert.AreEqual(new typeType( RepresentationTypes.Object, sName, "", false), result.Content.Headers.ContentType)
        assertNonExpiringCache result 
        Assert.IsNull(result.Headers.ETag)
        compareObject expected parsedResult

let GetServiceSimpleOnly(api : RestfulObjectsControllerBase) = 
        let sName = ttc "RestfulObjects.Test.Data.RestDataRepository"
        let argS = "x-ro-domain-model=simple"
        let url = sprintf  "http://localhost/services/%s?%s" sName argS

        let args = CreateReservedArgs argS

        api.Request <- jsonGetMsg(url)
        let result = api.GetService(sName, args)
        let jsonResult = readSnapshotToJson result
        let parsedResult = JObject.Parse(jsonResult)
        let mst = ttc "RestfulObjects.Test.Data.MostSimple"

        let expected = [ TProperty(JsonPropertyNames.ServiceId, TObjectVal(sName));
                         TProperty(JsonPropertyNames.Title, TObjectVal("Rest Data Repository"));
                         TProperty(JsonPropertyNames.Links, TArray([ TObjectJson(makeGetLinkProp RelValues.Self (sprintf "services/%s" sName)  RepresentationTypes.Object sName);
                                                                     //TObjectJson(makeIconLink())
                                                                      ]));
                         TProperty(JsonPropertyNames.Members, TObjectJson([TProperty("AzContributedAction", TObjectJson(makeServiceActionMemberSimple "AzContributedAction" sName mst));
                                                                           TProperty("AzContributedActionOnBaseClass", TObjectJson(makeServiceActionMemberSimple "AzContributedActionOnBaseClass" sName mst));
                                                                           TProperty("AzContributedActionWithRefParm", TObjectJson(makeServiceActionMemberSimple "AzContributedActionWithRefParm" sName mst));
                                                                           TProperty("AzContributedActionWithValueParm", TObjectJson(makeServiceActionMemberSimple "AzContributedActionWithValueParm" sName mst));
                                                                           TProperty("CreateTransientMostSimple", TObjectJson(makeServiceActionMemberNoParmsSimple "CreateTransientMostSimple" sName mst));
                                                                           TProperty("CreateTransientWithValue", TObjectJson(makeServiceActionMemberNoParmsSimple "CreateTransientWithValue" sName (ttc "RestfulObjects.Test.Data.WithValue")));
                                                                           TProperty("CreateTransientWithReference", TObjectJson(makeServiceActionMemberNoParmsSimple "CreateTransientWithReference" sName (ttc "RestfulObjects.Test.Data.WithReference")));
                                                                           TProperty("CreateTransientWithCollection", TObjectJson(makeServiceActionMemberNoParmsSimple "CreateTransientWithCollection" sName (ttc "RestfulObjects.Test.Data.WithCollection"))) ]));

                         TProperty(JsonPropertyNames.Extensions, TObjectJson([TProperty(JsonPropertyNames.DomainType, TObjectVal(sName));
                                                                              TProperty(JsonPropertyNames.FriendlyName, TObjectVal("Rest Data Repository"));
                                                                              TProperty(JsonPropertyNames.PluralName, TObjectVal("Rest Data Repositories"));
                                                                              TProperty(JsonPropertyNames.Description, TObjectVal(""));
                                                                              TProperty("serviceType", TObjectVal("menu"));
                                                                              TProperty(JsonPropertyNames.IsService, TObjectVal(true))]) )]

        Assert.AreEqual(HttpStatusCode.OK, result.StatusCode)
        Assert.AreEqual(new typeType( RepresentationTypes.Object, sName), result.Content.Headers.ContentType)
        assertNonExpiringCache result 
        Assert.IsTrue(result.Headers.ETag =  null)
        compareObject expected parsedResult
 
let GetServiceWithMediaType(api : RestfulObjectsControllerBase) = 
        let sName = ttc "RestfulObjects.Test.Data.RestDataRepository"
        let url = sprintf  "http://localhost/services/%s" sName
        let msg = jsonGetMsg(url)
        msg.Headers.Accept.Single().Parameters.Add(new NameValueHeaderValue ("profile", (makeProfile RepresentationTypes.Object)))

        let args = CreateReservedArgs ""

        api.Request <- msg
        let result = api.GetService(sName, args)
        let jsonResult = readSnapshotToJson result
        let parsedResult = JObject.Parse(jsonResult)
        let mst = ttc "RestfulObjects.Test.Data.MostSimple"

        let expected = [ TProperty(JsonPropertyNames.ServiceId, TObjectVal(sName));
                         TProperty(JsonPropertyNames.Title, TObjectVal("Rest Data Repository"));
                         TProperty(JsonPropertyNames.Links, TArray([ TObjectJson(makeGetLinkProp RelValues.Self (sprintf "services/%s" sName)  RepresentationTypes.Object sName);
                                                                     TObjectJson(makeGetLinkProp RelValues.DescribedBy (sprintf "domain-types/%s" sName)  RepresentationTypes.DomainType "");
                                                                     //TObjectJson(makeIconLink())
                                                                      ]));
                         TProperty(JsonPropertyNames.Members, TObjectJson([TProperty("AzContributedAction", TObjectJson(makeServiceActionMember "AzContributedAction" sName mst));
                                                                           TProperty("AzContributedActionOnBaseClass", TObjectJson(makeServiceActionMember "AzContributedActionOnBaseClass" sName mst));
                                                                           TProperty("AzContributedActionWithRefParm", TObjectJson(makeServiceActionMember "AzContributedActionWithRefParm" sName mst));
                                                                           TProperty("AzContributedActionWithValueParm", TObjectJson(makeServiceActionMember "AzContributedActionWithValueParm" sName mst));
                                                                           TProperty("CreateTransientMostSimple", TObjectJson(makeServiceActionMemberNoParms "CreateTransientMostSimple" sName mst));
                                                                           TProperty("CreateTransientWithValue", TObjectJson(makeServiceActionMemberNoParms "CreateTransientWithValue" sName (ttc "RestfulObjects.Test.Data.WithValue")));
                                                                           TProperty("CreateTransientWithReference", TObjectJson(makeServiceActionMemberNoParms "CreateTransientWithReference" sName (ttc "RestfulObjects.Test.Data.WithReference")));
                                                                           TProperty("CreateTransientWithCollection", TObjectJson(makeServiceActionMemberNoParms "CreateTransientWithCollection" sName (ttc "RestfulObjects.Test.Data.WithCollection"))) ]));

                         TProperty(JsonPropertyNames.Extensions, TObjectJson([TProperty(JsonPropertyNames.DomainType, TObjectVal(sName));
                                                                              TProperty(JsonPropertyNames.FriendlyName, TObjectVal("Rest Data Repository"));
                                                                              TProperty(JsonPropertyNames.PluralName, TObjectVal("Rest Data Repositories"));
                                                                              TProperty(JsonPropertyNames.Description, TObjectVal(""));
                                                                              TProperty("serviceType", TObjectVal("menu"));
                                                                              TProperty(JsonPropertyNames.IsService, TObjectVal(true))]) )]

        Assert.AreEqual(HttpStatusCode.OK, result.StatusCode)
        Assert.AreEqual(new typeType( RepresentationTypes.Object, sName), result.Content.Headers.ContentType)
        assertNonExpiringCache result      
        compareObject expected parsedResult    
    

    
let GetWithActionService(api : RestfulObjectsControllerBase) =   
        let oType = ttc "RestfulObjects.Test.Data.WithActionService"
        let oid = oType
        let url = sprintf "http://localhost/services/%s"  oid

        let args = CreateReservedArgs ""

        api.Request <-  jsonGetMsg(url)
        let result = api.GetService(oid, args)
        let jsonResult = readSnapshotToJson result
        let parsedResult = JObject.Parse(jsonResult)
        let mst = ttc "RestfulObjects.Test.Data.MostSimple"
      
        let expected = [ TProperty(JsonPropertyNames.ServiceId, TObjectVal(oid));
                         TProperty(JsonPropertyNames.Title, TObjectVal("With Action Service"));
                         TProperty(JsonPropertyNames.Links, TArray( [ TObjectJson( makeGetLinkProp RelValues.Self (sprintf "services/%s" oid)  RepresentationTypes.Object oType);
                                                                      TObjectJson(makeGetLinkProp RelValues.DescribedBy (sprintf "domain-types/%s" oid)  RepresentationTypes.DomainType "");
                                                                      //TObjectJson(makeIconLink())
                                                                       ]));
                         TProperty(JsonPropertyNames.Members, TObjectJson([TProperty("ADisabledAction", TObjectJson(TProperty(JsonPropertyNames.DisabledReason, TObjectVal("Always disabled")) ::makeServiceActionMemberNoParms "ADisabledAction"oid mst));
                                                                           TProperty("ADisabledCollectionAction", TObjectJson(TProperty(JsonPropertyNames.DisabledReason, TObjectVal("Always disabled")) ::makeServiceActionCollectionMemberNoParms "ADisabledCollectionAction"oid mst));
                                                                           TProperty("ADisabledQueryAction", TObjectJson(TProperty(JsonPropertyNames.DisabledReason, TObjectVal("Always disabled")) ::makeServiceActionCollectionMemberNoParms "ADisabledQueryAction"oid mst));
                                                                           TProperty("AnAction", TObjectJson(makeServiceActionMemberNoParms "AnAction" oid mst));
                                                                           TProperty("AnActionReturnsViewModel", TObjectJson(makeServiceActionMemberNoParms "AnActionReturnsViewModel" oid (ttc "RestfulObjects.Test.Data.MostSimpleViewModel")));
                                                                           TProperty("AnActionReturnsRedirectedObject", TObjectJson(makeServiceActionMemberNoParms "AnActionReturnsRedirectedObject" oid (ttc "RestfulObjects.Test.Data.RedirectedObject")));
                                                                           TProperty("AnActionReturnsWithDateTimeKey", TObjectJson(makeServiceActionMemberNoParms "AnActionReturnsWithDateTimeKey" oid (ttc "RestfulObjects.Test.Data.WithDateTimeKey")));
                                                                           TProperty("AnActionAnnotatedIdempotent", TObjectJson(makeServiceActionMemberNoParms "AnActionAnnotatedIdempotent" oid mst));
                                                                           TProperty("AnActionAnnotatedIdempotentReturnsViewModel", TObjectJson(makeServiceActionMemberNoParms "AnActionAnnotatedIdempotentReturnsViewModel" oid (ttc "RestfulObjects.Test.Data.MostSimpleViewModel")));
                                                                           TProperty("AnActionAnnotatedIdempotentReturnsNull", TObjectJson(makeServiceActionMemberNoParms "AnActionAnnotatedIdempotentReturnsNull" oid mst));
                                                                           TProperty("AnActionAnnotatedQueryOnly", TObjectJson(makeServiceActionMemberNoParms "AnActionAnnotatedQueryOnly" oid mst));
                                                                           TProperty("AnActionAnnotatedQueryOnlyReturnsViewModel", TObjectJson(makeServiceActionMemberNoParms "AnActionAnnotatedQueryOnlyReturnsViewModel" oid (ttc "RestfulObjects.Test.Data.MostSimpleViewModel")));
                                                                           TProperty("AnActionAnnotatedQueryOnlyReturnsNull", TObjectJson(makeServiceActionMemberNoParms "AnActionAnnotatedQueryOnlyReturnsNull" oid mst));
                                                                           TProperty("AnActionReturnsCollection", TObjectJson(makeServiceActionCollectionMemberNoParms "AnActionReturnsCollection" oid mst));     
                                                                           TProperty("AnActionReturnsCollectionEmpty", TObjectJson(makeServiceActionCollectionMemberNoParms "AnActionReturnsCollectionEmpty" oid mst));  
                                                                           TProperty("AnActionReturnsCollectionNull", TObjectJson(makeServiceActionCollectionMemberNoParms "AnActionReturnsCollectionNull" oid mst));                      
                                                                           TProperty("AnActionReturnsCollectionWithParameters", TObjectJson(makeServiceActionCollectionMember "AnActionReturnsCollectionWithParameters" oid mst));
                                                                           TProperty("AnActionReturnsCollectionWithScalarParameters", TObjectJson(makeServiceActionCollectionMember "AnActionReturnsCollectionWithScalarParameters" oid mst)); 
                                                                           TProperty("AnActionReturnsNull", TObjectJson(makeServiceActionMemberNoParms "AnActionReturnsNull" oid mst));
                                                                           TProperty("AnActionReturnsNullViewModel", TObjectJson(makeServiceActionMemberNoParms "AnActionReturnsNullViewModel" oid (ttc "RestfulObjects.Test.Data.MostSimpleViewModel")));
                                                                           TProperty("AnActionReturnsObjectWithParameterAnnotatedQueryOnly", TObjectJson(makeServiceActionMember "AnActionReturnsObjectWithParameterAnnotatedQueryOnly" oid mst));                                                                           
                                                                           TProperty("AnActionReturnsObjectWithParameters", TObjectJson(makeServiceActionMember "AnActionReturnsObjectWithParameters" oid mst));
                                                                           TProperty("AnActionReturnsObjectWithParametersAnnotatedIdempotent", TObjectJson(makeServiceActionMember "AnActionReturnsObjectWithParametersAnnotatedIdempotent" oid mst));
                                                                           TProperty("AnActionReturnsObjectWithParametersAnnotatedQueryOnly", TObjectJson(makeServiceActionMember "AnActionReturnsObjectWithParametersAnnotatedQueryOnly" oid mst));
                                                                           TProperty("AnActionReturnsQueryable", TObjectJson(makeServiceActionCollectionMemberNoParms "AnActionReturnsQueryable" oid mst));                          
                                                                           TProperty("AnActionReturnsQueryableWithParameters", TObjectJson(makeServiceActionCollectionMember "AnActionReturnsQueryableWithParameters" oid mst));
                                                                           TProperty("AnActionReturnsQueryableWithScalarParameters", TObjectJson(makeServiceActionCollectionMember "AnActionReturnsQueryableWithScalarParameters"oid mst)); 
                                                                           TProperty("AnActionReturnsScalar", TObjectJson(makeActionMemberNumber "services" "AnActionReturnsScalar" oid "An Action Returns Scalar" "" "integer" false));
                                                                           TProperty("AnActionReturnsScalarEmpty", TObjectJson(makeActionMemberString  "services"  "AnActionReturnsScalarEmpty" oid "An Action Returns Scalar Empty" "" "string" false));
                                                                           TProperty("AnActionReturnsScalarNull", TObjectJson(makeActionMemberString "services" "AnActionReturnsScalarNull" oid "An Action Returns Scalar Null" "" "string" false));
                                                                           TProperty("AnActionReturnsScalarWithParameters", TObjectJson(makeActionMemberNumber "services" "AnActionReturnsScalarWithParameters" oid "An Action Returns Scalar With Parameters" "" "integer" true));
                                                                           TProperty("AnActionReturnsVoid", TObjectJson(makeServiceActionVoidMember "AnActionReturnsVoid" oid));
                                                                           TProperty("AnActionReturnsVoidWithParameters", TObjectJson(makeVoidActionMember "services" "AnActionReturnsVoidWithParameters" oid "An Action Returns Void With Parameters" "an action for testing" true ));
                                                                           
                                                                           TProperty("AnActionValidateParameters", TObjectJson(makeActionMemberNumber "services" "AnActionValidateParameters" oid "An Action Validate Parameters" "" "integer" true));
                                                                           TProperty("AnActionWithDateTimeParm", TObjectJson(makeVoidActionMember "services" "AnActionWithDateTimeParm" oid "An Action With Date Time Parm" "" true));
                                                                           TProperty("AnActionWithOptionalParm", TObjectJson(makeServiceActionMember "AnActionWithOptionalParm" oid mst));
                                                                           TProperty("AnActionWithOptionalParmQueryOnly", TObjectJson(makeServiceActionMember "AnActionWithOptionalParmQueryOnly" oid mst));
                                                                           TProperty("AnActionWithParametersWithChoicesWithDefaults", TObjectJson(makeServiceActionMember "AnActionWithParametersWithChoicesWithDefaults"oid mst));
                                                                           TProperty("AnActionWithReferenceParameter", TObjectJson(makeServiceActionMember "AnActionWithReferenceParameter"oid mst));
                                                                           TProperty("AnActionWithReferenceParameterWithChoices", TObjectJson(makeServiceActionMember "AnActionWithReferenceParameterWithChoices"oid mst));
                                                                           TProperty("AnActionWithReferenceParameterWithDefault", TObjectJson(makeServiceActionMember "AnActionWithReferenceParameterWithDefault"oid mst));
                                                                           TProperty("AnActionWithValueParameter", TObjectJson(makeServiceActionMember "AnActionWithValueParameter"oid mst));
                                                                           TProperty("AnActionWithValueParameterWithChoices", TObjectJson(makeServiceActionMember "AnActionWithValueParameterWithChoices"oid mst));
                                                                           TProperty("AnActionWithValueParameterWithDefault", TObjectJson(makeServiceActionMember "AnActionWithValueParameterWithDefault"oid mst));
                                                                           TProperty("AnError", TObjectJson(makeActionMemberNumber "services" "AnError"oid  "An Error" "" "integer" false));
                                                                           TProperty("AnErrorCollection", TObjectJson(makeServiceActionCollectionMemberNoParms "AnErrorCollection"oid mst));
                                                                           TProperty("AnErrorQuery", TObjectJson(makeServiceActionCollectionMemberNoParms "AnErrorQuery"oid mst)) ]));
                         TProperty(JsonPropertyNames.Extensions, TObjectJson([TProperty(JsonPropertyNames.DomainType, TObjectVal(oType));
                                                                              TProperty(JsonPropertyNames.FriendlyName, TObjectVal("With Action Service"));
                                                                              TProperty(JsonPropertyNames.PluralName, TObjectVal("With Action Services"));
                                                                              TProperty(JsonPropertyNames.Description, TObjectVal(""));
                                                                              TProperty("serviceType", TObjectVal("menu"));
                                                                              TProperty(JsonPropertyNames.IsService, TObjectVal(true))]) )]

        Assert.AreEqual(HttpStatusCode.OK, result.StatusCode)
        Assert.AreEqual(new typeType( RepresentationTypes.Object, oType), result.Content.Headers.ContentType)
        assertNonExpiringCache result 
        Assert.IsNull(result.Headers.ETag )
        compareObject expected parsedResult

    
let InvalidGetService(api : RestfulObjectsControllerBase) = 
        let sName = ""
        let url = sprintf  "http://localhost/services/%s" sName

        let args = CreateReservedArgs ""

        api.Request <- jsonGetMsg(url)
        let result = api.GetService(sName, args)
        let jsonResult = readSnapshotToJson result
     
        Assert.AreEqual(HttpStatusCode.BadRequest, result.StatusCode)
        Assert.AreEqual("199 RestfulObjects \"Exception of type 'NakedObjects.Surface.BadRequestNOSException' was thrown.\"", result.Headers.Warning.ToString())
        Assert.AreEqual("", jsonResult)
    

    
let NotFoundGetService(api : RestfulObjectsControllerBase) = 
        let sName = ttc "RestfulObjects.Test.Data.NoSuchService"
        let url = sprintf  "http://localhost/services/%s" sName

        let args = CreateReservedArgs ""

        api.Request <- jsonGetMsg(url)
        let result = api.GetService(sName, args)
        let jsonResult = readSnapshotToJson result
        
        Assert.AreEqual(HttpStatusCode.NotFound, result.StatusCode)
        Assert.AreEqual(sprintf "199 RestfulObjects \"No such service %s\"" sName, result.Headers.Warning.ToString())
        Assert.AreEqual("", jsonResult)
    
     
let NotAcceptableGetServiceWrongMediaType(api : RestfulObjectsControllerBase) = 
        let sName = ttc "RestfulObjects.Test.Data.RestDataRepository"
        let url = sprintf  "http://localhost/services/%s" sName
        let args = CreateReservedArgs ""

        try 
            let msg = jsonGetMsg(url)
            msg.Headers.Accept.Single().Parameters.Add(new NameValueHeaderValue ("profile", (makeProfile RepresentationTypes.ObjectCollection)))

            api.Request <- msg
            let result = api.GetService(sName, args)
            Assert.Fail("expect exception")
        with 
            | :? HttpResponseException as ex -> Assert.AreEqual(HttpStatusCode.NotAcceptable, ex.Response.StatusCode)

